<?php
/**
 * 后台管理员登认证
 * Author: ZeonWang
 * Date: 2017/5/11
 * Time: 11:35
 * Created by PhpStorm.
 */

namespace App\Http\Controllers\JWT;

use App\Exceptions\AdminManageException;
use App\Http\Controllers\Controller;

use App\Http\Models\Admin;
use App\Http\Requests\Admin\LoginPostRequest;
use App\Services\AdminErrCode;
use App\Services\Utils\ApiChecker;
use App\Services\Utils\ApiResponser;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\JWTException;


class AdminAuthController extends Controller
{
    use ApiResponser,
        ApiChecker;

    /**
     *  职员的登录处理，返回token
     *
     * @param LoginPostRequest|Request $request
     * @return array|\Illuminate\Http\JsonResponse
     * @throws AdminManageException
     * @throws JWTException
     */
    public function login(LoginPostRequest $request)
    {
        $admin = $this->findAdmin($request->email);
            $this->checkItemExist($admin, '管理员');
    
        $token = $this->tryGenerateToken($request, $admin);

        return $this->response(compact('token'));
    }

    /**
     * @param $is_verified_email
     * @throws AdminManageException
     */
    private function passwordVerifyCheck($is_verified_email)
    {
        if (! $is_verified_email) {
            throw New AdminManageException(AdminErrCode::INVALID_PASSWORD, '密码错误');
        }
    }

    /**
     * @return array|\Illuminate\Http\Response
     * @throws AdminManageException
     */
    public function logout()
    {
        try {
            $logout = Auth::guard('admin')->logout();

            return $this->response(compact('token', 'logout'));
        } catch (\Exception $e) {
            throw New AdminManageException(AdminErrCode::TOKEN_ERROR, 'Token错误-admin-logout');
        }
    }
    
    /**
     * @param string $email
     * @return Admin|null
     */
    private function findAdmin($email)
    {
        return (new Admin)
            ->where('email', $email)
            ->orWhere('name', $email)
            ->orWhere('phonenum', $email)
            ->first();
    }
    
    /**
     * @param LoginPostRequest $request
     * @param $admin
     * @return mixed
     * @throws AdminManageException
     * @throws JWTException
     */
    private function tryGenerateToken(LoginPostRequest $request, Admin $admin)
    {
        try {
            /**
             * 不能用 credentials ，JWT 0.5.* 不能实现 multi auth
             * attempt to verify the credentials and create a token for the user
             * @see https://github.com/tymondesigns/jwt-auth/issues/513#issuecomment-186087297
             */
            $email_token = Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password]);
            $name_token = Auth::guard('admin')->attempt(['name' => $request->email, 'password' => $request->password]);
            $phone_token = Auth::guard('admin')->attempt(['phonenum' => $request->email, 'password' => $request->password]);
                $this->passwordVerifyCheck($email_token || $name_token || $phone_token);

            $token = $email_token ?: ($name_token ?: $phone_token);

            // save token
            $admin->update(['remember_token' => $token]);
        } catch (JWTException $e) {
            logger($e->getMessage());

            if (config('app.debug')) throw $e;
            
            throw New AdminManageException(AdminErrCode::TOKEN_GENERATE_FAIL, '无法生成Token');
        }
        
        return $token;
    }
}